package com.atguigu.day01;

import com.sun.jmx.snmp.tasks.ThreadService;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * tips:方法论:AB原则
 * 学习一个新技术
 * Before
 * After
 * 是谁 干嘛用的 从哪下载 怎么安装 用之前之后
 */

/**
 * @ClassName SaleTicketDemo
 * @Description 此类描述:多线程 操作 资源类--高内聚低耦合
 * @Author dangchen
 * @DateTime 2022-09-06 19:42
 * @Version 1.0
 */
class TrainTicket {//资源类
    private int number = 50;

    //1.synchronized
   /* public synchronized void sale(){
        if (number > 0){
            System.out.println(Thread.currentThread().getName() + "\t" + "卖出第:" + (number--) + "\t还剩下:" + number);
        }
    }*/

   //2.lock
    //lambda函数 @FunctionalInterface函数式接口 :就是一个有且仅有一个抽象方法，但是可以有多个非抽象方法的接口。
    // 拷贝小括号 写死右箭头 落地大括号

    Lock lock = new ReentrantLock(true);//独占锁+可重入锁+公平|默认非公平锁
    public void sale(){
        lock.lock();
        try {
            if (number > 0){
                System.out.println(Thread.currentThread().getName() + "\t" + "卖出第:" + (number--) + "\t还剩下:" + number);
            }
        }finally {
            lock.unlock();
        }
    }

}

public class SaleTicketDemo {
    public static void main(String[] args) {
        //TrainTicket trainTicket = new TrainTicket();

        //1.synchronized
        /*new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 51; i++) {
                    trainTicket.sale();
                }
            }
        },"A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 51; i++) {
                    trainTicket.sale();
                }
            }
        },"B").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 51; i++) {
                    trainTicket.sale();
                }
            }
        },"C").start();*/

        //2.lock
        /*new Thread(()-> { for (int i = 0; i < 51 ; i++) trainTicket.sale(); },"A").start();

        new Thread(() ->{ for (int i = 0; i < 51 ; i++) trainTicket.sale(); },"B").start();

        new Thread(()->{ for (int i = 0; i < 51 ; i++) trainTicket.sale(); },"C").start();*/

        //线程池
        TrainTicket trainTicket = new TrainTicket();
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        try {
            for (int i = 0; i < 60; i++) {
                threadPool.execute(() -> trainTicket.sale());
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }

    }
}
